package tools

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
)

func AddrJoin(addrInt uint16, addrFloat uint8) string {
	return fmt.Sprintf("%d.%d", addrInt, addrFloat)
}

func AddrSplit(address, mode string) (addrInt uint16, addrFloat uint8, err error) {
	var tmpInt int
	arr := strings.Split(address, ".")
	if len(arr) > 2 {
		err = errors.New("地址格式错误")
	}
	if len(arr) == 1 {
		tmpInt, err = strconv.Atoi(arr[0])
		if err != nil {
			err = errors.New("地址格式错误")
			return
		}
		addrInt = uint16(tmpInt)
		return
	}
	/*--- 整数部分 ---*/
	tmpInt, err = strconv.Atoi(arr[0])
	if err != nil {
		err = errors.New("地址格式错误")
		return
	}
	if tmpInt > 65535 {
		err = errors.New("PLC地址的整数部分超过65535")
		return
	}
	addrInt = uint16(tmpInt)
	/*--- 小数部分 ---*/
	tmpInt, err = strconv.Atoi(arr[1])
	if err != nil {
		err = errors.New("地址格式错误")
		return
	}
	if tmpInt > 15 {
		err = errors.New("PLC地址的小数部分超过15")
		return
	}
	addrFloat = uint8(tmpInt)
	if mode == "modbus" {
		if addrFloat > 15 {
			err = errors.New("汇川modbus地址小数部分超过15")
			return
		}
	} else {
		if addrFloat > 7 {
			err = errors.New("PLC地址小数部分超过7")
			return
		}
	}
	return
}

// PlcAddrToBytes PLC地址转换成字节
func PlcAddrToBytes(addr string, endian string, plcType uint8) (b [3]byte) {
	mode := "plc"
	if plcType == 3 {
		mode = "modbus"
	}
	addrInt, addrFloat, _ := AddrSplit(addr, mode)
	b1 := Uint16ToBytes(addrInt, endian)
	b[0] = b1[0]
	b[1] = b1[1]
	b[2] = addrFloat
	return
}

// PLCAddrBytesParse 解析电源模型PLC地址 (数据类型1字节,块2字节,地址整数2字节,地址小数1字节)
func PLCAddrBytesParse(data []byte, endian string) (plcType uint8, block uint16, addr string) {
	if len(data) != 6 {
		fmt.Printf("PLC地址解析错误,长度错误\n")
		return
	}
	plcType = data[0]
	block = BytesToUint16(data[1:3], endian)
	if plcType == 3 {
		addr = AddrJoin(BytesToUint16(data[3:5], endian), data[5])
	} else {
		addr = fmt.Sprintf("%d", BytesToUint16(data[3:5], endian))
	}
	return
}
